classdef AbstractActuator < handle
    %ABSTRACTACTUATOR �˴���ʾ�йش����ժҪ
    %   �˴���ʾ��ϸ˵��
    
    properties
        name
        type
        setting
        
        port
    end
    
    %%
    methods
        function obj = AbstractActuator(name, type, varargin)
            p=inputParser;
            p.addRequired('name', @ischar);
            p.addRequired('type', @(x) ismember(x, {'Coil', 'AOM', 'Eater'}));
            p.addParameter('filename', [Constant.AutoMeasurementAppPath strrep('\+Table1\Actuators.xml', '\', Constant.PathDelimiter)], @ischar);
            p.parse(name, type, varargin{:});

            obj.name = name;
            obj.type = type;
            obj.loadActuator(p.Results.filename);
        end
        
        function loadActuator(obj, filename)
            L = log4m.getLogger;
            
            info = xml_read(filename);            
            switch obj.type
                case 'Coil'
                    if ismember(obj.name, fields(info.Coil))
                        param.direction = info.Coil.(obj.name).direction;
                        param.nTurn = info.Coil.(obj.name).nTurn;
                        param.curr2nT = info.Coil.(obj.name).curr2nT;
                        param.inductance = info.Coil.(obj.name).inductance;
                        param.resistance = info.Coil.(obj.name).resistance;
                        L.info('AbstractActuator::loadActuator', sprintf('Coil [%s] infomation loaded.', obj.name));
                    else
                        error('No inforamtion [type = Coils, name = %s] found.', obj.name);
                    end
                case 'AOM'
                    if ismember(obj.name, fields(info.AOM))
                        param.model = info.AOM.(obj.name).model;
                        param.sn = info.AOM.(obj.name).sn;
                        param.voltFreq = info.AOM.(obj.name).voltFreq;
                        L.info('AbstractActuator::loadActuator', sprintf('AOM [%s] infomation loaded.', obj.name));
                    else
                        error('No inforamtion [type = AOMs, name = %s] found.', obj.name);
                    end
                case 'Eater'
                    if ismember(obj.name, fields(info.Eater))
                        param.model = info.Eater.(obj.name).model;
                        param.sn = info.Eater.(obj.name).sn;
                        param.range = info.Eater.(obj.name).range;
                        L.info('AbstractActuator::loadActuator', sprintf('Eater [%s] infomation loaded.', obj.name));
                    else
                        error('No inforamtion [type = Eaters, name = %s] found.', obj.name);
                    end
                case 'EOM'
                    if ismember(obj.name, fields(info.EOM))
                        param.model = info.NoiseEater.(obj.name).model;
                        param.sn = info.NoiseEater.(obj.name).sn;
                        L.info('AbstractActuator::loadActuator', sprintf('EOM [%s] infomation loaded.', obj.name));
                    else
                        error('No inforamtion [type = EOM, name = %s] found.', obj.name);
                    end
                otherwise
                    error('Unknown type [%s]', obj.type);
            end
            obj.setting = param;
        end
        
        %% configuration
        function obj = connect_to(obj, port)
            L = log4m.getLogger;
            p=inputParser;
            p.addRequired('port', @(x) isa(x, 'SignalChain.IOPort.OutputPort') || isa(x, 'SignalChain.IOPort.BidirectionPort'));
            p.parse(port);
            obj.port = port;
            L.info('AbstractActuator::connect_to', sprintf('%s [%s] connect to port [%s].', obj.type, obj.name, obj.port.name));
        end
        function obj = setDriver(obj, driver)
            L = log4m.getLogger;
            L.info('AbstractActuator::setDriver', sprintf('%s [%s] setting port driver [%s]...', obj.type, obj.name, driver.name));
            
            p=inputParser;
            p.addRequired('driver', @(x) strcmp(obj.port.device.device, x.device.device))
            p.parse(driver);
            obj.port.setDriver(driver);            
        end
        function obj = setOscillator(obj, oscillator)
            L = log4m.getLogger;
            L.info('AbstractActuator::setOscillator', sprintf('%s [%s] setting port oscillator [%s]...', obj.type, obj.name, oscillator));
            
            p=inputParser;
            p.addRequired('oscillator', @Miscellaneous.isZIindex4);
            p.parse(oscillator);
            obj.port.setOscillator(oscillator);
        end
        
        %% port operations
        function obj = reset(obj)
            L = log4m.getLogger;
            L.info('AbstractActuator::reset', sprintf('%s [%s] resetting port [%s]...', obj.type, obj.name, obj.port.name));
            obj.port.initialize();
        end
        function obj = enable(obj)
            L = log4m.getLogger;
            L.info('AbstractActuator::enable', sprintf('%s [%s] enabling port [%s]...', obj.type, obj.name, obj.port.name));
            obj.port.enable();
        end
        function obj = disable(obj)
            L = log4m.getLogger;
            L.info('AbstractActuator::disable', sprintf('%s [%s] disabling port [%s]...', obj.type, obj.name, obj.port.name));
            obj.port.disable();
        end
        
        %%
        function disp(obj)
            fprintf('%s [%s] is connected to port [%s]. \n\n', obj.type, obj.name, obj.port.name);
            disp(obj.port);
        end
    end
    
    %% output operations
    methods
        function setDC(obj, value)
            obj.port.setDC(value);
        end
        function setAC(obj, varargin)
            obj.port.setAC(varargin{:});
        end
        function setAWG(obj, waveform, varargin)
            obj.port.setAWG(waveform, varargin);
        end
    end
end

